from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_jwt.views import api_settings
from rest_framework.generics import GenericAPIView

from .models import OauthQQUser
from . import serializers
from carts.utils import merge_cart_cookie_to_redis
from .exceptions import QQAPIException
from .utils import OAuthQQ


# url(r'^qq/user/$', views.QQAuthUserView.as_view()),
# 用户扫码登录后的回调处理， 即最终获取openid，来判断用户是否是第一次使用三方登录

class QQAuthUserView(GenericAPIView):
    # 指定序列化器
    serializer_class = serializers.QQAuthUserSerializer

    def get(self, request):
        # 提取code请求参数
        code = request.query_params.get('code')
        if not code:
            return Response({'message': '缺少code'}, status=status.HTTP_400_BAD_REQUEST)
        # 创建QQ工具对象
        oauth = OAuthQQ()

        try:
            # 使用code向QQ服务器器请求access_token
            access_token = oauth.get_access_token(code)

            # 使用access_token向QQ服务器器请求openid
            openid = oauth.get_openid(access_token)
        except QQAPIException:
            return Response({'message': 'QQ服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 使用openid查询该QQ用户是否在美多商城中绑定过用户
        try:
            oauth_user = OauthQQUser.objects.get(openid=openid)
        except OauthQQUser.DoesNotExist:
            # 如果openid没绑定美多商城用户，post创建用户并绑定到openid
            # 为了后续工作前端可以使用openid， 需要将openid签名后响应给前端
            access_token_openid = OAuthQQ.generate_save_user_token(openid)
            return Response({'access_token': access_token_openid})

        else:
            # 如果openid已绑定美多商城用户，直接生成JWT token，并返回
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            # 获取openid关联的user
            user = oauth_user.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            # 获取响应对象
            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username,
            })

            # 调用合并购物车的工具方法
            response = merge_cart_cookie_to_redis(request=request, user=user, response=response)

            # 向前端响应 token  user_id   username
            return response

    def post(self, request):
        """使用openid绑定到用户，因为涉及两个模型类， 所以需要重写post"""
        # 获取序列化器对象
        serializer = self.get_serializer(data=request.data)
        # 开始校验
        serializer.is_valid(raise_exception=True)
        # 保存校验结果
        user = serializer.save()
        # 生成JWT_token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 构造响应对象
        response = Response({
            'token': token,
            'user_id': user.id,
            'username': user.username
        })

        # 调用合并购物车的工具方法
        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)

        # 返回jwt_token, user_id, username
        return response


# url(r'^qq/authorization/$', views.QQAuthURLView.as_view()),

# 定义视图，生成qq扫码登录的url响应给浏览器
class QQAuthURLView(APIView):
    def get(self, request):
        # 获取next参数，为了实现以后QQ登录成功后， 用户从哪个页面跳转过来的就回到哪个页面去
        next = request.query_params.get('next')
        # 生成QQ工具类
        oauth = OAuthQQ(state=next)
        # 生成QQ扫码链接
        login_url = oauth.get_qq_login_url()
        return Response({'login_url': login_url})
